package com.opencvjava.lessons.imgproc;

import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.Size;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
import org.springframework.stereotype.Service;

import static com.opencvjava.support.util.CvUtils.imshow;
import static com.opencvjava.support.util.CvUtils.mat;
import static org.opencv.core.Core.BORDER_DEFAULT;
import static org.opencv.core.Core.convertScaleAbs;
import static org.opencv.highgui.HighGui.waitKey;
import static org.opencv.imgproc.Imgproc.GaussianBlur;
import static org.opencv.imgproc.Imgproc.Sobel;
import static org.opencv.imgproc.Imgproc.cvtColor;

@Service
// sobel [-1, -2, -1; 0,0,0; 1, 2, 1] Scharr [-3, -10, -3; 0, 0,0; 3, 10, 3]
// 官方建议使用scharr
public class L10_SobelScharr {
    public void test() {
        // First we declare the variables we are going to use
        Mat src, src_gray = new Mat();
        Mat grad = new Mat();
        String window_name = "Sobel Demo - Simple Edge Detector";
        int scale = 1;
        int delta = 0;
        int ddepth = CvType.CV_16S;
        // Load the image
        src = mat("lena.jpg");
        // Check if image is loaded fine
        if (src.empty()) {
            throw new RuntimeException("图片读取失败");
        }
        // Remove noise by blurring with a Gaussian filter ( kernel size = 3 )
        GaussianBlur(src, src, new Size(3, 3), 0, 0, BORDER_DEFAULT);
        // Convert the image to grayscale
        cvtColor(src, src_gray, Imgproc.COLOR_RGB2GRAY);
        Mat grad_x = new Mat(), grad_y = new Mat();
        Mat abs_grad_x = new Mat(), abs_grad_y = new Mat();
        Imgproc.Scharr(src_gray, grad_x, ddepth, 1, 0, scale, delta, Core.BORDER_DEFAULT);
//        Sobel( src_gray, grad_x, ddepth, 1, 0, 3, scale, delta, BORDER_DEFAULT );
        Imgproc.Scharr(src_gray, grad_y, ddepth, 0, 1, scale, delta, Core.BORDER_DEFAULT);
//        Sobel( src_gray, grad_y, ddepth, 0, 1, 3, scale, delta, BORDER_DEFAULT );
        // converting back to CV_8U
        convertScaleAbs(grad_x, abs_grad_x);
        convertScaleAbs(grad_y, abs_grad_y);
        Core.addWeighted(abs_grad_x, 0.5, abs_grad_y, 0.5, 0, grad);
        imshow(window_name, grad);
    }
}
